import asyncio
import threading
import psycopg2
import aiopg
from setting import *

test_import = '这里是__init__.py'
#单例模式下的线程池用法
class ConnPG():
    _instance = None
    _initialized = False

    def __new__(cls, *args, **kwargs):  #去内存申请地址
        if not cls._instance:
            cls._instance = super().__new__(cls)
        return cls._instance

    def __init__(self, loop=None):  #可以传入一个指定的永久loop,
        if not self._initialized:
            #创建一个新的事件循环线程
            if loop == None:
                self.newlp = asyncio.new_event_loop()
                t = threading.Thread(target=self.thread_running_loop,
                                     args=(self.newlp, ))
                t.start()
            else:
                self.newlp = loop

            #创建线程池
            asyncio.run_coroutine_threadsafe(self.pools(), self.newlp)

            self._initialized = True

    def thread_running_loop(self, lp: asyncio.AbstractEventLoop):  #开启loop
        asyncio.set_event_loop(lp)  #在此线程中设置一个新的事件循环,默认情况下事件循环是主线程的
        lp.run_forever()

    async def pools(self):  #开启线程池的coro
        self.dsn = f"host={PS_HOST} port={PS_PORT} user={PS_USER} password={PS_PASSWORD} dbname={PS_DATABASE}"

        self.pool = await aiopg.create_pool(self.dsn)

        print("线程池开启完毕~~~")

    async def execute(self, sql:str, args:tuple=None) -> None:#aiops默认自动commit

        async with self.pool.acquire() as conn:
            async with conn.cursor() as cur:
                if args == None:
                    await cur.execute(sql)
                elif isinstance(args, tuple):
                    await cur.execute(sql, args)

    async def fetchone(self, sql:str, args:tuple=None):

        async with self.pool.acquire() as conn:
            async with conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor) as cur:
                if args == None:
                    await cur.execute(sql)
                elif isinstance(args, tuple):
                    await cur.execute(sql, args)

                result = await cur.fetchone()

        return result

    async def fetchall(self, sql:str, args:tuple=None):

        async with self.pool.acquire() as conn:
            async with conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor) as cur:
                if args == None:
                    await cur.execute(sql)
                elif isinstance(args, tuple):
                    await cur.execute(sql, args)

                result = await cur.fetchall()

        return result



    


